package jude.java.money.ant;

import static jude.java.money.ant.Defination.*;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.BuildException;

public class DynamicBlog extends Base {

	private String parameter;
	private int count;
	private String property;
	private String types;
	private String path;
	
	private static final String TYPE_MAIN = "main";
	private static final String TYPE_DOMAIN = "domain";
	private static final String TYPE_TITLE = "title";
	private static final String TYPE_THEME = "theme";
	private static final String TYPE_PERMALINK = "permalink";
	private static final String TYPE_USERNAME = "username";
	private static final String TYPE_TIME = "time";
	private static final String TYPE_AVATAR = "avatar";
	private static final String TYPE_EMAIL = "email";
	private static final String TYPE_PERMISSION = "permission";
	private static final String TYPE_PLUGIN = "plugin";
	private static final String TYPE_OTHER = "other";
	
	@Override
	public void execute() throws BuildException {
		if (TYPE_MAIN.equals(types)) {
			blogSQLs();
			return;
		} else if (TYPE_DOMAIN.equals(types)) {
			blogDomains();
			return;
		}
		handlerTypes();
	}
	
	private void handlerTypes() {
		String[] types = StringUtils.split(this.types, ",");
		StringBuilder sb = new StringBuilder("\r\n");
		List<String> themes = null;
		for (int i = 0; i <= count; i++) {
			String prefix = getPrefix(i);
			for (int j = 0; j < types.length; j++) {
				String type = types[j];
				if (TYPE_THEME.equals(type)) {
					if (themes == null)
						themes = getThemes();
					String theme = getTheme(themes);
					oo(sb, prefix, theme, "template", "stylesheet");
				} else if (TYPE_PERMALINK.equals(type)) {
					int r = random(PERMALINK_WEIGHTS, PERMALINKS.length);
					String permalink = PERMALINKS[r];
					String rule = REWRITE_RULES[r];
					oo(sb, prefix, permalink, "permalink_structure");
					oo(sb, prefix, rule, "rewrite_rules");
				} else if (TYPE_TITLE.equals(type)) {
					String title = getTitle();
					oo(sb, prefix, title, "blogname");
					String subtitle = getSubtitle();
					oo(sb, prefix, subtitle, "blogdescription");
				} else if (TYPE_USERNAME.equals(type)) {
					String name1 = NAMES[random(0, NAMES.length)];
					String name2 = NAMES[random(0, NAMES.length)];
					String name3 = NAMES[random(0, NAMES.length)];
					while (name2.equals(name1)) {
						name2 = NAMES[random(0, NAMES.length)];
					}
					while (name3.equals(name1) || name3.equals(name2)) {
						name3 = NAMES[random(0, NAMES.length)];
					}
					o(sb, prefix, name1, 1);
					o(sb, prefix, name2, 2);
					o(sb, prefix, name3, 3);
				} else if (TYPE_TIME.equals(type)) {
					String dateFormat = random(DATE_FORMAT);
					String timeFormat = random(TIME_FORMAT);
					String startOfWeek = random(START_OF_WEEK);
					oo(sb, prefix, dateFormat, "date_format");
					oo(sb, prefix, timeFormat, "time_format");
					oo(sb, prefix, startOfWeek, "start_of_week");
				} else if (TYPE_AVATAR.equals(type)) {
					String avatar = random(AVATAR_DEFAULT);
					oo(sb, prefix, avatar, "avatar_default");
				} else if (TYPE_EMAIL.equals(type)) {
					String email = getEmail();
					oo(sb, prefix, email, "admin_email");
				} else if (TYPE_PERMISSION.equals(type)) {
					updatePrefix(sb, "wp_", prefix);
				} else if (TYPE_PLUGIN.equals(type)) {
					sb.append("update `").append(prefix).append("options` set option_value='a:1:{i:0;s:36:\"google-sitemap-generator/sitemap.php\";}' where option_name='active_plugins';\r\n");
					String name = StringUtils.replace(prefix, "_", ".xml");
					sb.append("INSERT INTO `").append(prefix).append("options` (`option_id`, `blog_id`, `option_name`, `option_value`, `autoload`) VALUES (223, 0, 'sm_options', 'a:58:{s:18:\"sm_b_prio_provider\";s:41:\"GoogleSitemapGeneratorPrioByCountProvider\";s:13:\"sm_b_filename\";s:7:\"").append(name).append("\";s:10:\"sm_b_debug\";b:0;s:8:\"sm_b_xml\";b:1;s:9:\"sm_b_gzip\";b:1;s:9:\"sm_b_ping\";b:1;s:14:\"sm_b_pingyahoo\";b:0;s:13:\"sm_b_yahookey\";s:0:\"\";s:12:\"sm_b_pingask\";b:1;s:12:\"sm_b_pingmsn\";b:1;s:19:\"sm_b_manual_enabled\";b:0;s:17:\"sm_b_auto_enabled\";b:1;s:15:\"sm_b_auto_delay\";b:1;s:15:\"sm_b_manual_key\";s:32:\"0e9919029283763a24b51650d4410448\";s:11:\"sm_b_memory\";s:2:\"4M\";s:9:\"sm_b_time\";i:-1;s:14:\"sm_b_max_posts\";i:100;s:13:\"sm_b_safemode\";b:0;s:18:\"sm_b_style_default\";b:1;s:10:\"sm_b_style\";s:0:\"\";s:11:\"sm_b_robots\";b:1;s:12:\"sm_b_exclude\";a:0:{}s:17:\"sm_b_exclude_cats\";a:0:{}s:18:\"sm_b_location_mode\";s:4:\"auto\";s:20:\"sm_b_filename_manual\";s:39:\"E:\\\\Workspaces\\\\php\\\\wordpress/sitemap.xml\";s:19:\"sm_b_fileurl_manual\";s:22:\"http://wp2/sitemap.xml\";s:10:\"sm_in_home\";b:1;s:11:\"sm_in_posts\";b:1;s:15:\"sm_in_posts_sub\";b:0;s:11:\"sm_in_pages\";b:1;s:10:\"sm_in_cats\";b:1;s:10:\"sm_in_arch\";b:0;s:10:\"sm_in_auth\";b:0;s:10:\"sm_in_tags\";b:1;s:9:\"sm_in_tax\";a:0:{}s:13:\"sm_in_lastmod\";b:1;s:10:\"sm_cf_home\";s:6:\"weekly\";s:11:\"sm_cf_posts\";s:6:\"weekly\";s:11:\"sm_cf_pages\";s:6:\"weekly\";s:10:\"sm_cf_cats\";s:6:\"weekly\";s:10:\"sm_cf_auth\";s:6:\"weekly\";s:15:\"sm_cf_arch_curr\";s:6:\"weekly\";s:14:\"sm_cf_arch_old\";s:6:\"yearly\";s:10:\"sm_cf_tags\";s:6:\"weekly\";s:10:\"sm_pr_home\";d:1;s:11:\"sm_pr_posts\";d:0.59999999999999997779553950749686919152736663818359375;s:15:\"sm_pr_posts_min\";d:0.200000000000000011102230246251565404236316680908203125;s:11:\"sm_pr_pages\";d:0.59999999999999997779553950749686919152736663818359375;s:10:\"sm_pr_cats\";d:0.299999999999999988897769753748434595763683319091796875;s:10:\"sm_pr_arch\";d:0.299999999999999988897769753748434595763683319091796875;s:10:\"sm_pr_auth\";d:0.299999999999999988897769753748434595763683319091796875;s:10:\"sm_pr_tags\";d:0.299999999999999988897769753748434595763683319091796875;s:12:\"sm_i_donated\";b:0;s:17:\"sm_i_hide_donated\";b:0;s:17:\"sm_i_install_date\";i:1304405198;s:14:\"sm_i_hide_note\";b:0;s:15:\"sm_i_hide_works\";b:0;s:16:\"sm_i_hide_donors\";b:0;}', 'yes');");
				} else if (TYPE_OTHER.equals(type)) {
					oo(sb, prefix, "1", "enable_xmlrpc");			//XML-RPC
				}
			}
			sb.append("\r\n");
		}
		out(sb.toString());
	}
	
	private void o(StringBuilder sb, String prefix, String name, int id) {
		sb.append("update `").append(prefix).append("users` set user_nicename='").append(niceValue(name)).append("', display_name='").append(sqlValue(name)).append("' where ID=").append(id).append(";\r\n");
		sb.append("update `").append(prefix).append("usermeta` set meta_value='").append(sqlValue(name)).append("' where user_id=").append(id).append(" and meta_key='nickname';\r\n");
	}

	private void blogSQLs() {
		try {
			String f = getAbsolutePath(parameter);
			String sql = readFile(f, "GBK");
			FileWriter out = new FileWriter(new File(getAbsolutePath(path)));
			String[] tables = {"commentmeta", "comments", "links", "options", "postmeta", "posts", "terms", "term_relationships", "term_taxonomy", "usermeta", "users"};
			out.write(sql);
			String p = "wp_";
			for (int i = 1; i <= count; i++) {
				out.write("\r\n");
				String prefix = getPrefix(i);
				String c = sql;
				for (int j = 0; j < tables.length; j++) {
					c = StringUtils.replace(c, p + tables[j], prefix + tables[j]);
				}
				out.write(c);
			}
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void updatePrefix(StringBuilder sb, String from, String to) {
		if (StringUtils.equals(from, to))
			return;
		//替换字段名
		o(sb, from, to, "options", "option_name", "user_roles");
		o(sb, from, to, "usermeta", "meta_key", "capabilities");
		o(sb, from, to, "usermeta", "meta_key", "user_level");
		o(sb, from, to, "usermeta", "meta_key", "user-settings");
		o(sb, from, to, "usermeta", "meta_key", "user-settings-time");
		o(sb, from, to, "usermeta", "meta_key", "dashboard_quick_press_last_post_id");
		//替换配置值
		o(sb, from, to, "options", "sidebars_widgets");
		o(sb, from, to, "options", "cron");
	}
	
	private void o(StringBuilder sb, String from, String to, String table, String column, String key) {
		sb.append("update `").append(to).append(table).append("` set ").append(column).append("='").append(to).append(key).append("' where ").append(column).append("='").append(from).append(key).append("';\r\n");
	}
	private void o(StringBuilder sb, String from, String to, String table, String key) {
		sb.append("update `").append(to).append(table).append("` set option_value").append("=replace(option_value").append(",'\"").append(from).append("','\"").append(to).append("') where option_name='").append(key).append("';\r\n");
	}
	
	private void blogDomains() {
		StringBuilder sb = new StringBuilder();
		int n = 0;
		String domains = get("DOMAINS");
		if (StringUtils.isEmpty(domains)) {
			for (int i = 0; i < 10000; i++) {
				String domain = get("DOMAINS_" + (i + 1));
				if (StringUtils.isBlank(domain))
					break;
				if (i % 10 == 0)
					sb.append("\r\n");
				if (i > 0)
					sb.append(",");
				sb.append("'");
				sb.append(domain.trim().toLowerCase());
				sb.append("'");
				n ++;
			}
		} else {
			String[] ds = StringUtils.split(domains, ",");
			for (int i = 0; i < ds.length; i++) {
				if (StringUtils.isBlank(ds[i]))
					continue;
				if (i % 10 == 0)
					sb.append("\r\n\t");
				if (i > 0)
					sb.append(",");
				sb.append("'");
				sb.append(ds[i].toLowerCase());
				sb.append("'");
				n ++;
			}
		}
		set(property, sb.toString());
		if (getInteger(get("BLOG_COUNT"), -1) == -1)
			set("BLOG_COUNT", String.valueOf(n));
	}
	
	private void out(String content) {
		if (StringUtils.isNotEmpty(property)) {
			set(property, content);
		} else if (StringUtils.isNotEmpty(path)){
			try {
				FileWriter w = new FileWriter(getAbsolutePath(path), true);
				w.write(content);
				w.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private static String getEmail() {
		String email = random(EMAILS);
		if (email.contains("@"))
			return email;
		int n = random(-1, email.length());
		if (n <= 0)
			return email + "@gmail.com";
		return email.substring(0, n) + "." + email.substring(n) + "@gmail.com";
	}
	
	private static String getTitle() {
//		return TITLES[random(0, TITLES.length)];
		return random(TITLES, SONGS, OTHER);
	}

	private String getSubtitle() {
		String tpl = getTemplate();
		tpl = replace(tpl, "{SURNAME}", SURNAME);
		tpl = replace(tpl, "{NAME}", NAMES);
		tpl = replace(tpl, "{PLACE}", PLACES);
		tpl = replace(tpl, "{ADJ}", ADJS);
		tpl = replace(tpl, "{NOUN}", NOUNS);
		return tpl;
	}
	
	private String sqlValue(String str) {
		return StringUtils.replace(str, "'", "''");
	}
	
	private String niceValue(String str) {
		str = StringUtils.replaceChars(str, "'\"\\/<>?%", "-");
		return str.toLowerCase();
	}
	
	private String getTemplate() {
		return TPLS[random(TPL_WEIGHTS, TPLS.length)];
	}
	
	private String replace(String tpl,String key, String[] values) {
		if (tpl.indexOf(key) == -1)
			return tpl;
		String value = sqlValue(values[random(0, values.length)]);
		return StringUtils.replace(tpl, key, value);
	}
	
	private void oo(StringBuilder sb, String prefix, String value, String... keys) {
		//INSERT INTO users (username, email) VALUES ('Jo', 'jo@email.com') ON DUPLICATE KEY UPDATE email = 'jo@email.com'
		sb.append("update `").append(prefix).append("options` set option_value='").append(sqlValue(value)).append("' where option_name='").append(keys[0]).append("'");
		for (int i = 1; i < keys.length; i++) {
			sb.append(" or option_name='").append(keys[i]).append('\'');
		}
		sb.append(";\r\n");
	}
	
	private String getPrefix(int index) {
		return index == 0 ? "wp_" : ("wp" + index + "_");
//		return "wp" + (index == 0 ? "" : String.valueOf(index)) + "_";
	}
	
	private List<String> getThemes() {
		String themePath = parameter;
		File f = new File(themePath);
		if (!f.exists() && !f.isAbsolute()) {
			themePath = getProject().getBaseDir() + "\\" + themePath;
			f = new File(themePath);
		}
		ArrayList<String> a = new ArrayList<String>();
		if (f.exists() && f.isDirectory()) {
			File[] fs = f.listFiles();
			boolean dir = true;
			for (int i = 0; i < fs.length; i++) {
				String name = fs[i].getName();
				if (name.startsWith("."))
					continue;
				if (dir && fs[i].isDirectory())
					a.add(name);
			}
		}
		return a;
	}
	
	private String getTheme(List<String> themes) {
		int i = random(0, themes.size());
		return themes.get(i);
	}
	
	/***
	 *  min to max-1
	 */
	public static int random(int min, int max) {
		if (max < min) {
			int t = max;
			max = min;
			min = t;
		}
		java.util.Random r = new java.util.Random();
		return r.nextInt(max - min) + min;
	}
	
	private static int random(int[] weights, int count) {
		if (count <= 0)
			count = weights.length;
		int total = 0;
		for (int i = 0; i < count; i++) {
			if (i >= weights.length)
				total ++;
			else
				total += weights[i];
		}
		int r = random(0, total);	//0 to total-1
		if (r == 0)
			return 0;
		int c = 0;
		for (int i = 0; i < count; i++) {
			if (i >= weights.length)
				c ++;
			else
				c += weights[i];
			if (r < c)
				return i;
		}
		return count - 1;
	}
	
	private static String random(String[]... vals) {
		if (vals.length == 1) {
			return vals[0][random(0, vals[0].length)];
		}
		int[] weights = new int[vals.length];
		for (int i = 0; i < weights.length; i++) {
			weights[i] = vals[i] == null ? 0 : vals[i].length;
		}
		int r = random(weights, 0);
		return vals[r][random(0, vals[r].length)];
	}
	
	public String getParameter() {
		return parameter;
	}

	public void setParameter(String themesPath) {
		this.parameter = themesPath;
	}

	public int getCount() {
		return count;
	}
	
	public void setCount(int count) {
		this.count = count;
	}
	
	public String getProperty() {
		return property;
	}

	public void setProperty(String property) {
		this.property = property;
	}
	
	public String getTypes() {
		return types;
	}
	
	public void setTypes(String type) {
		this.types = type;
	}
	
	public String getPath() {
		return path;
	}
	
	public void setPath(String path) {
		this.path = path;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 50; i++) {
			System.out.println(getEmail());
		}
	}
}
